﻿using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Runtime.Caching;
using System.Runtime.Caching.Hosting;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Modularity;

namespace Qianke.Core.Common.NameMutex
{
    public class NameMutexManager : INameMutexManager, IScopedDependency
    {
        private IAbpLazyServiceProvider services;
        private readonly IOptions<NameMutexOptions> options;

        public NameMutexManager(IAbpLazyServiceProvider serviceCollection,IOptions<NameMutexOptions> options)
        {
            this.services = serviceCollection;
            this.options = options;
        }

        public async Task<INameMutex> CreateMutex(string mutexName)
        {
            
            INameMutex mutexInfo = null;
            switch (options.Value.MutexTypeName)
            {
                case "Local":
                    mutexInfo = services.GetRequiredService<LocalNameMutex>();
                    break;
                case "Redis":
                    mutexInfo = services.GetRequiredService<RedisNameMutex>();
                    break;
                default:
                    throw new Exception("未找到类型 ：INameMutex 的实例11");
            }
            if (mutexInfo == null)
                throw new Exception($"未找到类型 ：INameMutex 的实例");
            await mutexInfo.InitializeAsync(mutexName);
            return mutexInfo;
        }



        public async Task<NameMutexCollection> CreateMutex(IEnumerable<string> nameList)
        {
            return new NameMutexCollection(await nameList.SelectAsync(x => CreateMutex(x)));
        }

        public Task<INameMutex> CreateMutex<TModel>(object key)
        {
            return CreateMutex($"{typeof(TModel).Name}:{key}");
        }

        public Task<INameMutex> CreateMutex<TModel>(TModel model, object key)
        {
            return CreateMutex<TModel>(key);
        }

        public Task<INameMutex> CreateMutex<TModel>(TModel model, Func<TModel, object> getKey)
        {
            return CreateMutex<TModel>(getKey(model));
        }
    }
}
